home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / yacc / flexyacc / aflex.lha / aflex / src / ascan_io.a < prev    next >
Text File  |  1993-05-31  |  8KB  |  289 lines

  1. with ascan_dfa; use ascan_dfa; 
  2. with text_io; use text_io;
  3.  
  4. package ascan_io is
  5. user_input_file : file_type;
  6. user_output_file : file_type;
  7. NULL_IN_INPUT : exception;
  8. AFLEX_INTERNAL_ERROR : exception;
  9. UNEXPECTED_LAST_MATCH : exception;
  10. PUSHBACK_OVERFLOW : exception;
  11. AFLEX_SCANNER_JAMMED : exception;
  12. type eob_action_type is ( EOB_ACT_RESTART_SCAN,
  13.                           EOB_ACT_END_OF_FILE,
  14.                           EOB_ACT_LAST_MATCH );
  15. YY_END_OF_BUFFER_CHAR :  constant character:=  ASCII.NUL;
  16. yy_n_chars : integer;       -- number of characters read into yy_ch_buf
  17.  
  18. -- true when we've seen an EOF for the current input file
  19. yy_eof_has_been_seen : boolean;
  20.  
  21. procedure YY_INPUT(buf: out unbounded_character_array; result: out integer; max_size: in integer);
  22. function yy_get_next_buffer return eob_action_type;
  23. procedure yyunput( c : character; yy_bp: in out integer );
  24. procedure unput(c : character);
  25. function input return character;
  26. procedure output(c : character);
  27. function yywrap return boolean;
  28. procedure Open_Input(fname : in String);
  29. procedure Close_Input;
  30. procedure Create_Output(fname : in String := "");
  31. procedure Close_Output;
  32. end ascan_io;
  33.  
  34. package body ascan_io is
  35. -- gets input and stuffs it into 'buf'.  number of characters read, or YY_NULL,
  36. -- is returned in 'result'.
  37.  
  38. procedure YY_INPUT(buf: out unbounded_character_array; result: out integer; max_size: in integer) is
  39.     c : character;
  40.     i : integer := 1;
  41.     loc : integer := buf'first;
  42. begin
  43.     if (is_open(user_input_file)) then
  44.       while ( i <= max_size ) loop
  45.          if (end_of_line(user_input_file)) then -- Ada ate our newline, put it back on the end.
  46.              buf(loc) := ASCII.LF;
  47.              skip_line(user_input_file, 1);
  48.          else
  49.            get(user_input_file, buf(loc));
  50.          end if;
  51.  
  52.          loc := loc + 1;
  53.          i := i + 1;
  54.       end loop;
  55.     else
  56.       while ( i <= max_size ) loop
  57.          if (end_of_line) then -- Ada ate our newline, put it back on the end.
  58.              buf(loc) := ASCII.LF;
  59.              skip_line(1);
  60.  
  61.          else
  62.              get(buf(loc));
  63.          end if; 
  64.  
  65.          loc := loc + 1;
  66.          i := i + 1;
  67.       end loop;
  68.     end if; -- for input file being standard input
  69.  
  70.     result := i - 1; 
  71.     exception
  72.         when END_ERROR => result := i - 1;
  73.     -- when we hit EOF we need to set yy_eof_has_been_seen
  74.     yy_eof_has_been_seen := true;
  75. end YY_INPUT;
  76.  
  77. -- yy_get_next_buffer - try to read in new buffer
  78. --
  79. -- returns a code representing an action
  80. --     EOB_ACT_LAST_MATCH - 
  81. --     EOB_ACT_RESTART_SCAN - restart the scanner
  82. --     EOB_ACT_END_OF_FILE - end of file
  83.  
  84. function yy_get_next_buffer return eob_action_type is
  85.     dest : integer := 0;
  86.     source : integer := yytext_ptr - 1; -- copy prev. char, too
  87.     number_to_move : integer;
  88.     ret_val : eob_action_type;
  89.     num_to_read : integer;
  90. begin    
  91.     if ( yy_c_buf_p > yy_n_chars + 1 ) then
  92.         raise NULL_IN_INPUT;
  93.     end if;
  94.  
  95.     -- try to read more data
  96.  
  97.     -- first move last chars to start of buffer
  98.     number_to_move := yy_c_buf_p - yytext_ptr;
  99.  
  100.     for i in 0..number_to_move - 1 loop
  101.         yy_ch_buf(dest) := yy_ch_buf(source);
  102.     dest := dest + 1;
  103.     source := source + 1;
  104.     end loop;
  105.         
  106.     if ( yy_eof_has_been_seen ) then
  107.     -- don't do the read, it's not guaranteed to return an EOF,
  108.     -- just force an EOF
  109.  
  110.     yy_n_chars := 0;
  111.     else
  112.     num_to_read := YY_BUF_SIZE - number_to_move - 1;
  113.  
  114.     if ( num_to_read > YY_READ_BUF_SIZE ) then
  115.         num_to_read := YY_READ_BUF_SIZE;
  116.         end if;
  117.  
  118.     -- read in more data
  119.     YY_INPUT( yy_ch_buf(number_to_move..yy_ch_buf'last), yy_n_chars, num_to_read );
  120.     end if;
  121.     if ( yy_n_chars = 0 ) then
  122.     if ( number_to_move = 1 ) then
  123.         ret_val := EOB_ACT_END_OF_FILE;
  124.     else
  125.         ret_val := EOB_ACT_LAST_MATCH;
  126.         end if;
  127.  
  128.     yy_eof_has_been_seen := true;
  129.     else
  130.     ret_val := EOB_ACT_RESTART_SCAN;
  131.     end if;
  132.     
  133.     yy_n_chars := yy_n_chars + number_to_move;
  134.     yy_ch_buf(yy_n_chars) := YY_END_OF_BUFFER_CHAR;
  135.     yy_ch_buf(yy_n_chars + 1) := YY_END_OF_BUFFER_CHAR;
  136.  
  137.     -- yytext begins at the second character in
  138.     -- yy_ch_buf; the first character is the one which
  139.     -- preceded it before reading in the latest buffer;
  140.     -- it needs to be kept around in case it's a
  141.     -- newline, so yy_get_previous_state() will have
  142.     -- with '^' rules active
  143.  
  144.     yytext_ptr := 1;
  145.  
  146.     return ret_val;
  147. end yy_get_next_buffer;
  148.  
  149. procedure yyunput( c : character; yy_bp: in out integer ) is
  150.     number_to_move : integer;
  151.     dest : integer;
  152.     source : integer;
  153.     tmp_yy_cp : integer;
  154. begin
  155.     tmp_yy_cp := yy_c_buf_p;
  156.     yy_ch_buf(tmp_yy_cp) := yy_hold_char; -- undo effects of setting up yytext
  157.  
  158.     if ( tmp_yy_cp < 2 ) then
  159.     -- need to shift things up to make room
  160.     number_to_move := yy_n_chars + 2; -- +2 for EOB chars
  161.     dest := YY_BUF_SIZE + 2;
  162.     source := number_to_move;
  163.  
  164.     while ( source > 0 ) loop
  165.         dest := dest - 1;
  166.         source := source - 1;
  167.             yy_ch_buf(dest) := yy_ch_buf(source);
  168.     end loop;
  169.  
  170.     tmp_yy_cp := tmp_yy_cp + dest - source;
  171.     yy_bp := yy_bp + dest - source;
  172.     yy_n_chars := YY_BUF_SIZE;
  173.  
  174.     if ( tmp_yy_cp < 2 ) then
  175.         raise PUSHBACK_OVERFLOW;
  176.     end if;
  177.     end if;
  178.  
  179.     if ( tmp_yy_cp > yy_bp and then yy_ch_buf(tmp_yy_cp-1) = ASCII.LF ) then
  180.     yy_ch_buf(tmp_yy_cp-2) := ASCII.LF;
  181.     end if;
  182.  
  183.     tmp_yy_cp := tmp_yy_cp - 1;
  184.     yy_ch_buf(tmp_yy_cp) := c;
  185.  
  186. --  Note:  this code is the text of YY_DO_BEFORE_ACTION, only
  187. --         here we get different yy_cp and yy_bp's
  188.     yytext_ptr := yy_bp;
  189.     yy_hold_char := yy_ch_buf(tmp_yy_cp);
  190.     yy_ch_buf(tmp_yy_cp) := ASCII.NUL;
  191.     yy_c_buf_p := tmp_yy_cp;
  192. end yyunput;
  193.  
  194. procedure unput(c : character) is
  195. begin
  196.      yyunput( c, yy_bp );
  197. end unput;
  198.  
  199. function input return character is
  200.     c : character;
  201.     yy_cp : integer := yy_c_buf_p;
  202. begin
  203.     yy_ch_buf(yy_cp) := yy_hold_char;
  204.  
  205.     if ( yy_ch_buf(yy_c_buf_p) = YY_END_OF_BUFFER_CHAR ) then
  206.     -- need more input
  207.     yytext_ptr := yy_c_buf_p;
  208.     yy_c_buf_p := yy_c_buf_p + 1;
  209.  
  210.     case yy_get_next_buffer is
  211.         -- this code, unfortunately, is somewhat redundant with
  212.         -- that above
  213.  
  214.         when EOB_ACT_END_OF_FILE =>
  215.         if ( yywrap ) then
  216.             yy_c_buf_p := yytext_ptr;
  217.             return ASCII.NUL;
  218.         end if;
  219.  
  220.         yy_ch_buf(0) := ASCII.LF;
  221.         yy_n_chars := 1;
  222.         yy_ch_buf(yy_n_chars) := YY_END_OF_BUFFER_CHAR;
  223.         yy_ch_buf(yy_n_chars + 1) := YY_END_OF_BUFFER_CHAR;
  224.         yy_eof_has_been_seen := false;
  225.         yy_c_buf_p := 1;
  226.         yytext_ptr := yy_c_buf_p;
  227.         yy_hold_char := yy_ch_buf(yy_c_buf_p);
  228.  
  229.         return ( input );
  230.         when EOB_ACT_RESTART_SCAN =>
  231.         yy_c_buf_p := yytext_ptr;
  232.  
  233.         when EOB_ACT_LAST_MATCH =>
  234.         raise UNEXPECTED_LAST_MATCH;
  235.         when others => null;
  236.         end case;
  237.     end if;
  238.  
  239.     c := yy_ch_buf(yy_c_buf_p);
  240.     yy_c_buf_p := yy_c_buf_p + 1;
  241.     yy_hold_char := yy_ch_buf(yy_c_buf_p);
  242.  
  243.     return c;
  244. end input;
  245.  
  246. procedure output(c : character) is
  247. begin
  248.     if (is_open(user_output_file)) then
  249.       text_io.put(user_output_file, c);
  250.     else
  251.       text_io.put(c);
  252.     end if;
  253. end output;
  254.  
  255. -- default yywrap function - always treat EOF as an EOF
  256. function yywrap return boolean is
  257. begin
  258.     return true;
  259. end yywrap;
  260.  
  261. procedure Open_Input(fname : in String) is
  262. begin
  263.     yy_init := true;
  264.     open(user_input_file, in_file, fname);
  265. end Open_Input;
  266.  
  267. procedure Create_Output(fname : in String := "") is
  268. begin
  269.     if (fname /= "") then
  270.         create(user_output_file, out_file, fname);
  271.     end if;
  272. end Create_Output;
  273.  
  274. procedure Close_Input is
  275. begin
  276.    if (is_open(user_input_file)) then
  277.      text_io.close(user_input_file);
  278.    end if;
  279. end Close_Input;
  280.  
  281. procedure Close_Output is
  282. begin
  283.    if (is_open(user_output_file)) then
  284.      text_io.close(user_output_file);
  285.    end if;
  286. end Close_Output;
  287.  
  288. end ascan_io;
  289.